/*
 *  Created at 2011-01-31 01:44 GMT-03:00
 *  Author: Victor Williams Stafusa da Silva
 *  JSmartUnit
 */
package org.jsmartunit.model;

import java.util.Collection;

import org.jsmartunit.model.TestOrder.DescriptionFactory;

import org.junit.runner.Describable;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.manipulation.Sortable;
import org.junit.runner.manipulation.Sorter;

/**
 * @author Victor Williams Stafusa da Silva
 */
public class RunnerDescriptions<T extends Describable> implements DescriptionFactory<T>, Sortable, Filterable {

    private TestOrder<T> order;
    private final Collection<T> unordered;

    public RunnerDescriptions(Collection<T> unordered) {
        this.order = new TestOrder<T>(this);
        this.unordered = unordered;
    }

    @Override
    public Collection<T> getUnorderedElements() {
        return unordered;
    }

    public Collection<T> getFilteredElements() {
        return order.getFilteredChildren();
    }

    @Override
    public Description getDescription(T element) {
        return element.getDescription();
    }

    @Override
    public void sort(Sorter sorter) {
        order = order.derive(sorter);
    }

    @Override
    public void filter(Filter filter) throws NoTestsRemainException {
        order = order.derive(filter);
    }

    public void filterSilently(Filter filter) {
        order = order.deriveSilently(filter);
    }

    public void update() {
        for (T child : getFilteredElements()) {
            try {
                if (child instanceof Filterable) ((Filterable) child).filter(order.getFilter());
                if (child instanceof Sortable) ((Sortable) child).sort(order.getSorter());
            } catch (NoTestsRemainException e) {
                // Ignore it.
            }
        }
    }
}
